﻿#pragma once

#include <learn/geom/vec.h>

namespace xi
{

namespace mesh
{

using namespace xi::geom;

struct Material
{
    std::string name;
    Vec3f Ka;  // 环境光
    Vec3f Kd;  // 漫反射
    Vec3f Ks;  // 镜面反射
    Vec3f Ke;  // 自发光
    Vec3f Kt;  // 透射
    float Ns;  // 高光系数
    float Ni;  // 折射指数
    Vec3f Tf;  // 透射滤镜
    float d;   // 不透明度
    int illum; // 光照模型

    std::string map_Ka;   // 环境光贴图
    std::string map_Kd;   // 漫反射贴图
    std::string map_Ks;   // 镜面反射贴图
    std::string map_Ke;   // 自发光贴图
    std::string map_Kt;   // 透射贴图
    std::string map_Ns;   // 高光系数贴图
    std::string map_Ni;   // 折射指数贴图
    std::string map_d;    // 不透明度贴图
    std::string map_bump; // 凹凸贴图
};

struct EXT_SYMBOL Mesh_Data
{
  private:
    struct _Impl
    {
        std::vector<Vec3f> vertices;
        std::vector<Vec3f> normals;
        std::vector<Vec2f> texcoords;
        std::vector<unsigned int> indices;
        std::shared_ptr<Material> material;

        _Impl() = default;
        _Impl(_Impl &&) = delete;
    };

    std::shared_ptr<_Impl> m_impl;

  public:
    // 注意这里必须创建一个指针，否则 m_impl 将为空
    Mesh_Data() : m_impl(std::make_shared<_Impl>())
    {
    }

    _Impl *operator->() const noexcept
    {
        return m_impl.get();
    }

    /**
     * @brief 从 obj 文件中读取三维网格数据
     *
     * @param[in] path
     * @param[in] scale
     */
    void read(const char *path, float scale = 1.0f);
};

} // namespace mesh

} // namespace xi
